#include <OGF/quick_start/common/property_smoother.h>


#include <OGF/quick_start/common/select_util.h>

namespace OGF 
{
	/**
	* Given the property values in K, smooth them with simple
	* laplacian smoothing, for several iterations.
	*
	* @param K attribute to smooth
	* @param iterations number of iterations to smooth for
	* @param surface Surface to smooth on
	* @param lambda Smoothing strength constant
	*/
	void PropertySmoother::smooth(MapVertexAttribute<double> *K, int iterations, Surface *surface, double lambda)
	{
		MapVertexAttribute<double> K_swap(surface);
		MapVertexAttribute<double> *K2 = &K_swap;

		for(int i=0;i<iterations;i++)
		{
			FOR_EACH_VERTEX(Map, surface, v1)
			{
				Map::Vertex *v2;
				double K_v1 = (*K)[v1];
				double inv_degree = 1.0/(v1->degree());
				double dK = 0;
				FOR_EACH_ADJACENT_VERTEX(v1, v2)
				{
					//double dist2 = (v2->point() - v1->point()).norm2();
					dK += inv_degree*( (*K)[v2] - K_v1);
				}
				(*K2)[v1] = K_v1 + lambda*dK;
			}
			MapVertexAttribute<double> *temp = K2;
			K2 = K;
			K = temp;
		}
		// K is the last thing we updated.
		// If it is the duplicate, then write back to the real one
		if( K == &K_swap)
		{
			FOR_EACH_VERTEX(Map, surface, v)
			{
				(*K2)[v] = (*K)[v];
			}
		}
	}

}